import { getRoot, setRoot, patchRoot, makeInitialData } from './shared/storage.js';
import { LOGI, LOGW, LOGE, LOGD } from './shared/log.js';

const DEFAULT_GROUP_ID = 'default';
const DEFAULT_GROUP = { id: DEFAULT_GROUP_ID, name: '未分组', order: 10 };

const HTTP_PATTERN = /^https?:\/\//i;

chrome.runtime.onInstalled.addListener(async () => {
  try {
    const existing = await getRoot();
    if (!existing) {
      await setRoot(makeInitialData());
      LOGI('BG', '初始化存储完成');
    } else {
      LOGD('BG', '检测到已有存储');
    }
  } catch (err) {
    LOGE('BG', '初始化存储失败', err);
  }
});

chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
  try {
    if (!message) { sendResponse?.({ ok: false, message: 'empty_message' }); return true; }
    if (message.type === 'GCE_ADD_BOOKMARK') {
      handleAddBookmark(message.payload)
        .then(sendResponse)
        .catch((err) => {
          try { LOGE('BG', '收藏失败', err); } catch {}
          try { sendResponse({ ok: false, message: err?.message || '收藏失败' }); } catch {}
        });
      return true;
    }
    if (message.type === 'GCE_REMOVE_BOOKMARK') {
      handleRemoveBookmark(message.payload)
        .then(sendResponse)
        .catch((err) => {
          try { LOGE('BG', '取消收藏失败', err); } catch {}
          try { sendResponse({ ok: false, message: err?.message || '取消收藏失败' }); } catch {}
        });
      return true;
    }
    // 未识别类型
    sendResponse?.({ ok: false, message: 'unknown_message_type' });
    return true;
  } catch (err) {
    try { LOGE('BG', 'onMessage 同步异常', err); } catch {}
    try { sendResponse({ ok: false, message: err?.message || 'internal_error' }); } catch {}
    return true;
  }
});

async function handleAddBookmark(payload) {
  const url = (payload?.url || '').trim();
  const title = (payload?.title || '').trim();
  if (!url || !HTTP_PATTERN.test(url)) {
    return { ok: false, message: '仅支持收藏 http(s) 链接' };
  }

  let root = await getRoot();
  if (!root) {
    root = makeInitialData();
    await setRoot(root);
  }

  const bookmarks = Array.isArray(root.bookmarks) ? [...root.bookmarks] : [];
  const groups = Array.isArray(root.groups) ? [...root.groups] : [];
  const settings = root.settings || {};

  const sortedGroups = groups.slice().sort((a, b) => (a.order ?? 0) - (b.order ?? 0));
  const firstGroupId = sortedGroups[0]?.id;

  let targetGroupId = (payload?.groupId || '').trim() || firstGroupId || DEFAULT_GROUP_ID;
  if (targetGroupId && !groups.some((g) => g.id === targetGroupId)) {
    targetGroupId = firstGroupId || DEFAULT_GROUP_ID;
  }
  if (!targetGroupId) {
    targetGroupId = DEFAULT_GROUP_ID;
  }

  const already = bookmarks.find((item) => item.url === url);
  if (already) {
    return { ok: true, duplicated: true };
  }

  if (!groups.length) {
    groups.push({ ...DEFAULT_GROUP });
    targetGroupId = DEFAULT_GROUP_ID;
  }

  const now = Date.now();
  const nextOrder = calcNextOrder(bookmarks, targetGroupId);
  const bookmark = {
    id: genId('bm-'),
    title: title || url,
    url,
    groupId: targetGroupId,
    createdAt: now,
    updatedAt: now,
    order: nextOrder,
  };

  bookmarks.push(bookmark);

  await patchRoot({ bookmarks, groups });

  try {
    await chrome.runtime.sendMessage({ type: 'GCE_BOOKMARKS_UPDATED' });
  } catch (err) {
    // 未必有监听方，忽略错误
    LOGW('BG', '广播书签更新失败或无监听者', err);
  }

  return { ok: true, duplicated: false };
}

async function handleRemoveBookmark(payload) {
  const url = (payload?.url || '').trim();
  if (!url) return { ok: false, message: '无效链接' };
  let root = await getRoot();
  if (!root) {
    return { ok: true, removed: false };
  }
  const bookmarks = Array.isArray(root.bookmarks) ? [...root.bookmarks] : [];
  const settings = root.settings || {};
  const idx = bookmarks.findIndex((b) => b && b.url === url);
  if (idx === -1) {
    return { ok: true, removed: false };
  }
  const removed = bookmarks.splice(idx, 1)[0];
  try {
    const oldDock = Array.isArray(settings.dockIds) ? settings.dockIds.slice() : [];
    const nextDock = oldDock.filter((id) => id !== removed.id);
    const patch = { bookmarks, settings: { ...settings, dockIds: nextDock, dockStamp: Date.now() } };
    await patchRoot(patch);
  } catch (err) {
    await patchRoot({ bookmarks });
  }
  try {
    await chrome.runtime.sendMessage({ type: 'GCE_BOOKMARKS_UPDATED' });
  } catch (err) {
    LOGW('BG', '广播书签更新失败或无监听者', err);
  }
  return { ok: true, removed: true };
}

function calcNextOrder(list, groupId) {
  const filtered = Array.isArray(list)
    ? list.filter((item) => (item.groupId || DEFAULT_GROUP_ID) === groupId)
    : [];
  const max = filtered.reduce((acc, item) => Math.max(acc, item.order || 0), 0);
  return Math.ceil((max + 10) / 10) * 10;
}

function genId(prefix = '') {
  try {
    if (crypto?.getRandomValues) {
      const buf = new Uint32Array(2);
      crypto.getRandomValues(buf);
      const rand = Array.from(buf).map((n) => n.toString(16)).join('');
      return `${prefix}${Date.now().toString(36)}-${rand}`;
    }
  } catch (err) {
    console.warn('[GCE] 生成随机 ID 时出现异常，使用备用方案', err);
  }
  return `${prefix}${Date.now().toString(36)}-${Math.random().toString(16).slice(2)}`;
}
